package com.study.aop.theory.myaop;

import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;


/**
 * 简易IOC容器
 *
 * 也可以用ApplicationContext方式来表现^-^
 *
 * @author: chenhs
 * @date: Created in 15:36 2019/12/8
 **/
public class IocContainer {

    /**简化版bean定义Map*/
    private Map<String, Class<?>> beanDefinitionMap = new HashMap<>();

    /**用户的切面可能会有多个，简化给一个作为代表*/
    private Aspect aspect;


    public void addBeanDefinition(String beanName, Class<?> beanClass) {
        this.beanDefinitionMap.put(beanName, beanClass);
    }

    public Object getBean(String beanName) throws InstantiationException, IllegalAccessException {
        //需要能得到用户给定的bean定义
        Object bean = createInstance(beanName);
        //返回一个加工了的对象（代理）
        bean = proxyEnhance(bean);

        return bean;
    }


    private Object proxyEnhance(Object bean) {
        //如何进行代理增强
        if (this.aspect != null && bean.getClass().getName().matches(this.aspect.getPointcut().getClassPattern())) {
           //Jdk动态代理实现
           return Proxy.newProxyInstance(bean.getClass().getClassLoader()
                   , bean.getClass().getInterfaces()
                    , new AopInvocationHandler(bean, aspect));
        }

        return bean;
    }

    private Object createInstance(String beanName) throws IllegalAccessException, InstantiationException {
        return this.beanDefinitionMap.get(beanName).newInstance();
    }

    public Aspect getAspect() {
        return aspect;
    }

    public void setAspect(Aspect aspect) {
        this.aspect = aspect;
    }
}
